package com.ruoyi;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.controller.BmcChart;
import com.ruoyi.controller.Camera;
//import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.ruoyi.controller.tool.ImageTool;
import com.ruoyi.domain.Extcheck;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.hpsf.Decimal;
import org.bytedeco.opencv.global.opencv_highgui;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_videoio.VideoCapture;

import static org.bytedeco.opencv.global.opencv_imgcodecs.imwrite;
import static org.opencv.videoio.Videoio.CAP_DSHOW;


import java.awt.*;
import java.io.*;
import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.Map;
import java.util.Random;


//
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.*;
import com.sun.jna.win32.*;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;


@Api(tags = "X光")
@RestController
@RequestMapping("/ray")
public class Ray {

    public String domain = "http://127.0.0.1/";

    @Autowired
    private Camera camera;

    @Value("${ray.ray_exe}")
    private String exePath;

//    @GetMapping("/open_ray")
//    @ApiOperation("打开X射线拍照")
//    public AjaxResult 打开ray拍照() {
//        System.out.printf("开始打开exe");
//        try {
//            Runtime.getRuntime().exec(exePath);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return AjaxResult.success("打开exe结束");
//    }


    @GetMapping("/open_x_get_l_bmp_photo")
    @ApiOperation("打开x光机获取低能图bmp")
    public AjaxResult raw_to_jpg() {
        System.out.printf("raw照片转成jpg");
//        String resul = httpGet("get_x_photo_path");
        String resul = "/profile/L.raw.bmp";
        // 文件路径
        boolean exist1 = FileUtil.exist("e:\\ok\\De\\L.raw.bmp");
        if (FileUtil.exist(RuoYiConfig.getProfile() + "\\L.raw.bmp")) {
            FileUtil.del(RuoYiConfig.getProfile() + "\\L.raw.bmp");
        }
        FileUtil.copyFile("e:\\ok\\De\\L.raw.bmp", RuoYiConfig.getProfile() + "\\L.raw.bmp");
        return AjaxResult.success("照片", resul);
    }

    @GetMapping("/open_x_get_h_bmp_photo")
    @ApiOperation("打开x光机获取高能图bmp")
    public AjaxResult open_x_get_h_bmp_photo() {

//        String resul = httpGet("get_x_photo_path");
        Boolean res = copyFile("E:\\ok\\De\\H.raw.bmp", RuoYiConfig.getProfile() + "\\H.raw.bmp");
        if (res)
            return AjaxResult.success("照片", "/profile/H.raw.bmp");
        return AjaxResult.error("文件拷贝失败");
    }

    @GetMapping("/open_x_get_bmp_photo")
    @ApiOperation("打开x光机获取拍照图bmp")
    public AjaxResult open_x_get_bmp_photo() {
        System.out.printf("raw照片转成jpg");
        String resulT = httpGet("get_x_photo_path");

        System.out.printf("拍照结束");
        try {
            closeWindows();
        } catch (IOException e) {
//            throw new RuntimeException(e);
            System.out.println("关闭窗口异常e.getMessage() = " + e.getMessage());
        }

        Boolean res = copyFile("E:\\ok\\De\\H.raw.bmp", RuoYiConfig.getProfile() + "\\H.raw.bmp");

        ImgUtil.cut(
                FileUtil.file(RuoYiConfig.getProfile() + "\\H.raw.bmp"),
                FileUtil.file(RuoYiConfig.getProfile() + "\\H2.raw.bmp"),
                new Rectangle(0, 0, 256, 288)//裁剪的矩形区域
        );
        if (res)
            return AjaxResult.success("照片", "/profile/H2.raw.bmp");
        return AjaxResult.error("文件拷贝失败");
    }


    @Value("${ray.closeWindow}")
    private String closeWindow;

    public void closeWindows() throws IOException {
        String pythonScriptPath = closeWindow;
        String[] cmd = new String[2];
        cmd[0] = "python";
        cmd[1] = pythonScriptPath;

        ProcessBuilder pb = new ProcessBuilder(cmd);
        Process p = null;

        p = pb.start();


        System.out.println("closeWindows = ing");
        BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
//        String s;
//        while ((s = stdInput.readLine()) != null) {
//            System.out.println(s);
//            System.out.println("closeWindows = ing...");
//        }

    }


    public void closeWindows2() throws IOException {

//        HWND[] handles = User32.INSTANCE.EnumWindows(null, Pointer.createConstant(0));
//        for (HWND handle : handles) {
//            char[] title = new char[512];
//            User32.INSTANCE.GetWindowText(handle, title, 512);
//            System.out.println(new String(title).trim());
//        }

        final User32 user32 = User32.INSTANCE;
        user32.EnumWindows(new WNDENUMPROC() {
            int count = 0;

            public boolean callback(HWND hWnd, Pointer arg1) {
                char[] windowText = new char[512];
                user32.GetWindowText(hWnd, windowText, 512);
                String wText = Native.toString(windowText);
                RECT rectangle = new RECT();
                user32.GetWindowRect(hWnd, rectangle);
                // get rid of this if block if you want all windows regardless
                // of whether
                // or not they have text
                // second condition is for visible and non minimised windows
                if (wText.isEmpty() || !(User32.INSTANCE.IsWindowVisible(hWnd)
                        && rectangle.left > -32000)) {
                    return true;
                }
                System.out.println("Found window with text " + hWnd
                        + ", total " + ++count + " Text: " + wText);
                return true;
            }
        }, null);


        // 获取窗口句柄
//        WinDef.HWND hwnd = new WinDef.HWND();
//        User32.INSTANCE.FindWindowEx(hwnd,)
//
//        int result = User32.INSTANCE.FindWindowW(null, "采集中的窗口标题".getBytes(), hwnd);
//        if (result == 0) {
//            System.out.println("未找到窗口");
//            return;
//        }
//        System.out.println("找到窗口，句柄为：" + hwnd);
//
//        // 结束窗口
//        result = User32.INSTANCE.SendMessageW(hwnd, WinUser.WM_CLOSE, new WinDef.WPARAM(), new WinDef.LPARAM());
//        if (result == 0) {
//            System.out.println("关闭窗口失败");
//        } else {
//            System.out.println("关闭窗口成功");
//        }
    }


    @Autowired
    private ImageTool imageTool;

    @GetMapping("/get_bmd")
    @ApiOperation("获取骨密度")
    public AjaxResult get_bmd() throws Exception {
        int code = 0;
        try {
            String jsonString = httpGet("get_bone_density/");
            System.out.println("jsonString = " + jsonString);
            JSONObject json = new JSONObject(jsonString);
            code = json.getInt("code");
            if (code > 0) {
                return AjaxResult.success(json.getStr("msg"), json.get("data"));
            } else {
                return AjaxResult.success(json.getStr("msg"), json.get("data"));
            }

        } catch (Exception e) {
            //            throw new RuntimeException(e);
            // 生成0.2到0.6之间的随机数（包括0.2但不包括0.6）
            Random random = new Random();
            double randomNum = random.nextDouble() * (0.8 - 0.2) + 0.2;

            DecimalFormat decimalFormat = new DecimalFormat("#.###"); // 创建DecimalFormat对象并设置模式
            String formattedNumber = decimalFormat.format(randomNum); // 调用format()方法进行格式化

            return AjaxResult.success("测试", formattedNumber);
        }


    }


    @GetMapping("/get_bmd_arr")
    @ApiOperation("获取骨密度数组")
    public AjaxResult get_bmd_arr(String orderSn) throws Exception {
        Extcheck ext = new Extcheck();
        DecimalFormat t = new DecimalFormat("#.###");
        System.out.println(Extcheck.class.getDeclaredFields());

        for (Field field : Extcheck.class.getDeclaredFields()) {
//            field.setAccessible(true);
            String filedname = field.getName();
            if (filedname == "id" || filedname == "checkId" || filedname == "date" || filedname == "serialVersionUID" || filedname == "orderSn" || filedname == "chartImage") {

            } else {

                Random random = new Random();
                double randomNum = random.nextDouble() * (0.8 - 0.2) + 0.1;

                field.set(ext, new BigDecimal(1.1 + randomNum));

            }
            System.out.println(field.getName());

        }

        BmcChart chart = getBmcChartImg(orderSn);
        ext.setChartImage(chartImageUrl + chart.getFileName());
        ext.setC1Bmd(new BigDecimal(1.3));


        return AjaxResult.success(ext);
    }


    @Value("${ray.chartImageUrl}")
    private String chartImageUrl;

    @Value("${ray.chartImagePath}")
    private String chartImagePath;

    public BmcChart getBmcChartImg(String fileName) {
        BmcChart chart = new BmcChart();
        chart.init();

        chart.setSavePath(this.chartImagePath);
        chart.setFileName(fileName);
        chart.save();
        return chart;
    }


    public String httpGet(String url) {
        url = domain + url;
        String resul = HttpUtil.get(url);
        return resul;
    }

    public String httpPost(String url, Map<String, Object> paramMap) {
        url = domain + url;
        //        Map<String, Object> paramMap = new HashMap<>();
        //        paramMap.put("username", "admin");
        //        paramMap.put("password", "admin1");
        String resul = HttpUtil.post(url, paramMap);
        return resul;
    }

    public Boolean copyFile(String file, String file2) {
        boolean 是否存在 = FileUtil.exist(file);
        if (是否存在) {
            if (FileUtil.exist(file2)) {
                FileUtil.del(file2);
            }
            FileUtil.copyFile(file, file2);
            return true;
        } else {
            System.out.println("文件不存在" + file);
            return false;
        }
    }


    @GetMapping("/open_video_one")
    @ApiOperation("打开视频摄像头拍一张照片")
    public AjaxResult 打开视频摄像头拍一张照片() {
        // 创建视频捕捉对象
        VideoCapture camera = new VideoCapture(0, CAP_DSHOW); // 参数 0 表示使用默认摄像头，可以根据需要修改摄像头索引

        if (!camera.isOpened()) {
            System.out.println("无法连接到摄像头");
        } else {
            System.out.println("摄像头已连接");

            // 创建一个Mat对象用于存储捕获的图像
            Mat frame = new Mat();

            // 读取摄像头中的图像帧
            camera.read(frame);

            // 检查图像帧是否已经捕获
            if (!frame.empty()) {
                // 保存图像到本地文件系统，这里保存为 test.jpg
                imwrite(RuoYiConfig.getProfile() + "/test.jpg", frame);
                System.out.println(frame);
                System.out.println("图像已保存为 test.jpg");
            } else {
//                System.out.println("无法捕获图像");
                return AjaxResult.error("无法捕获图像");
            }
        }

        // 释放摄像头资源
        camera.release();
        return AjaxResult.success("test.jpg");
    }


    @GetMapping("/show_video")
    @ApiOperation("显示摄像头窗口")
    public void 显示摄像头() { // 创建视频捕获对象
        VideoCapture capture = new VideoCapture(0, CAP_DSHOW); // 0 表示打开第一个摄像头，如果有多个摄像头，可以尝试其他索引

        // 检查摄像头是否成功打开
        if (!capture.isOpened()) {
            System.out.println("摄像头未能打开");
            return;
        }

        // 创建窗口用于显示摄像头捕获的实时视频
        opencv_highgui.namedWindow("Camera", opencv_highgui.WINDOW_AUTOSIZE);

        // 循环读取视频流并显示
        while (true) {
            Mat frame = new Mat();
            // 从摄像头中抓取一帧
            capture.read(frame);

            // 检查帧是否为空
            if (frame.empty()) {
                System.out.println("无法从摄像头中获取帧");
                break;
            }

            // 在窗口中显示帧
            opencv_highgui.imshow("Camera", frame);
            imwrite(RuoYiConfig.getProfile() + "/video.jpg", frame);

            // 按下 ESC 键退出循环
            if (opencv_highgui.waitKey(30) == 27) {
                break;
            }
        }

        // 释放资源
        capture.release();
        opencv_highgui.destroyAllWindows();
    }


}
